package com.youxuan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youxuan.enums.AppHttpCodeEnum;
import com.youxuan.enums.GlobalConst;
import com.youxuan.exception.SystemException;
import com.youxuan.mapper.OrderMapper;
import com.youxuan.pojo.entity.*;
import com.youxuan.pojo.vo.*;
import com.youxuan.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl  extends ServiceImpl<OrderMapper,Order> implements OrderService {

    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderGoodsService orderGoodsService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private UserService userService;
    @Autowired
    private PlaceService placeService;
    @Autowired
    private CartDetailService cartDetailService;
 

    @Override
    public ResponseResult<List<OrderItemVo>> getList(Long uid) {
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getCreateBy, uid);
        queryWrapper.orderByDesc(Order::getCreateTime);
        List<Order> orders = orderMapper.selectList(queryWrapper);

        List<OrderItemVo> orderItemVos = orders.stream().map(order -> {
            OrderItemVo orderItemVo = new OrderItemVo();
            String orderCode = order.getOrderCode();
            orderItemVo.setOrderCode(orderCode);
            orderItemVo.setPriceTotal(order.getTotalPrice());
            orderItemVo.setCreateDate(order.getCreateTime());

            List<GoodsVo> goodsVos = getGoodsVosByOrderCode(orderCode);

            orderItemVo.setGoodsList(goodsVos);

            return orderItemVo;

        }).collect(Collectors.toList());

        return ResponseResult.okResult(orderItemVos);
    }

    @Override
    public ResponseResult<List<OrderItemVo>> getList() {
        if (!isAdmin()){
            throw new SystemException(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }
        List<Order> orders = orderMapper.selectList(null);

        List<OrderItemVo> orderList = orders.stream().map(order -> {
            OrderItemVo orderItemVo = new OrderItemVo();
            String orderCode = order.getOrderCode();
            orderItemVo.setOrderCode(orderCode);
            orderItemVo.setPriceTotal(order.getTotalPrice());
            orderItemVo.setCreateDate(order.getCreateTime());

            return orderItemVo;

        }).collect(Collectors.toList());

        return ResponseResult.okResult(orderList);
    }

    private List<GoodsVo> getGoodsVosByOrderCode(String orderCode) {
        List<OrderGoods> orderGoodsList = orderGoodsService.getGoodsListByOid(orderCode);
        return orderGoodsList.stream().map(orderGoods -> {
            Goods goods = goodsService.getGoods(orderGoods.getGId());
            GoodsVo goodsVo = new GoodsVo();
            BeanUtils.copyProperties(goods, goodsVo);
            goodsVo.setNum(orderGoods.getNum());
            return goodsVo;
        }).collect(Collectors.toList());
    }

    @Override
    public OrderDetailVo getOrderDetailByOid(String orderCode) {
        OrderDetailVo orderDetailVo = new OrderDetailVo();

        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getOrderCode, orderCode);
        Order orders = orderMapper.selectOne(queryWrapper);
        orderDetailVo.setOrderCode(orders.getOrderCode());
        orderDetailVo.setCreateTime(orders.getCreateTime());
        orderDetailVo.setPriceTotal(orders.getTotalPrice());
        orderDetailVo.setOrderStatus(orders.getOrderStatus());
        UserVo userVo = userService.getUserInfo(orders.getCreateBy());
        orderDetailVo.setUserVo(userVo);

        orderDetailVo.setPlace(placeService.getById(orders.getPId()));

        List<GoodsVo> goodsVoList = getGoodsVosByOrderCode(orders.getOrderCode());

        orderDetailVo.setGoodsVos(goodsVoList);

        return orderDetailVo;
    }

    @Override
    @Transactional
    public Order addOrder(AddOrderParamsVo addOrderParamsVo) {
        Order order = new Order();
        order.setPId(addOrderParamsVo.getPlaceId());
        order.setCreateBy(addOrderParamsVo.getUserId());
        order.setUpdateBy(addOrderParamsVo.getUserId());
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        String orderCode = IdWorker.getIdStr();
        order.setOrderCode(orderCode);
        order.setOrderStatus(1);

        double totalPrice = 0.00;
        String[] goodsIds = addOrderParamsVo.getGoodsIds().split(",");
        for (String goodsId1 : goodsIds) {
            Long goodsId = Long.parseLong(goodsId1);
            GoodsVo goodsDetail = cartDetailService.getCartGoodsDetail(goodsId, addOrderParamsVo.getUserId());
            totalPrice += goodsDetail.getPrice() * goodsDetail.getNum();
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setGId(goodsId);
            orderGoods.setOrderCode(orderCode);
            orderGoods.setNum(goodsDetail.getNum());
            orderGoods.setPrice(goodsDetail.getPrice());
            orderGoodsService.save(orderGoods);
            cartDetailService.deleteCartGoods(addOrderParamsVo.getUserId(), goodsId);
        }
        order.setTotalPrice(totalPrice);
        orderMapper.insert(order);
        return order;
    }

    public boolean isAdmin(){
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication().getPrincipal();
        String type = loginUser.getUser().getType();
        return type.equals(GlobalConst.Admin);
    }
}
